<template>
  <div class="update-photo">
    <img :src="img" alt="" class="img" ref="img" />
    <!-- 操作栏开始 -->
    <div class="toolbar">
      <div class="cancel" @click="$emit('close')">取消</div>
      <div class="confirm" @click="onConfirm">完成</div>
    </div>
    <!-- 操作栏结束 -->
  </div>
</template>

<script>
// 导入图片裁切的样式
import "cropperjs/dist/cropper.css";
// 导入图片裁切的js
import Cropper from "cropperjs";
// 更新用户照片资料
import { updateUserPhoto } from "@/api/user";
export default {
  name: "UpdatePhoto",
  props: {
    // 在子组件中使用 props 接收到传递的数据，并渲染到组件中
    img: {
      type: [String, Object],
      required: true,
    },
  },
  data() {
    return {
      // 定义裁剪js实例对象；方便在mounted使用new创建以后和后续在methods使用
      cropper: null,
    };
  },
  mounted() {
    // 获取上传的图片dom对象
    const image = this.$refs.img;
    // mounted()要确保渲染dom完成再拿
    // this.cropper = new Cropper(参数一，参数二)
    // 参数一：上传的图片dom对象
    // 参数二：裁切配置项对象
    this.cropper = new Cropper(image, {
      // aspectRatio: 16 / 9,
      // crop(event) {
      //   console.log(event.detail.x);
      //   console.log(event.detail.y);
      //   console.log(event.detail.width);
      //   console.log(event.detail.height);
      //   console.log(event.detail.rotate);
      //   console.log(event.detail.scaleX);
      //   console.log(event.detail.scaleY);
      // },

      viewMode: 1,
      dragMode: "move",
      aspectRatio: 1,
      autoCropArea: 1,
      cropBoxMovable: false,
      cropBoxResizable: false,
      background: false,
      movable: true,
    });

    //  console.log(cropper)
  },
  methods: {
    // 点击确认
    onConfirm() {
      // 基于服务端的裁切使用 getData 方法获取裁切参数
      // console.log(this.cropper.getData())

      // 纯客户端的裁切使用 getCroppedCanvas 获取裁切的文件对象
      this.cropper.getCroppedCanvas().toBlob((blob) => {
        console.log(blob);
        // 调用修改的方法
        this.updateUserPhoto(blob);
      });
    },
    // 修改方法写在点击确认中太冗长；抽离出来写
    async updateUserPhoto(blob) {
      this.$toast.loading({
        message: "保存中...",
        forbidClick: true, // 禁止背景点击
        duration: 0, // 持续展示
      });

      try {
        // 错误的用法
        // 如果接口要求 Content-Type 是 application/json
        // 则传递普通 JavaScript 对象
        // updateUserPhoto({
        //   photo: blob
        // })
        // 如果接口要求 Content-Type 是 multipart/form-data
        // 则你必须传递 FormData 对象
        // 一般上传数据给后端需要使用formdata对象装载
        const formData = new FormData();
        // FormData 接口的append() 方法 会添加一个新值到 FormData 对象内的一个已存在的键中，如果键不存在则会添加该键。
        // FormData.set 和 append() 的区别在于，如果指定的键已经存在， FormData.set 会使用新值覆盖已有的值，而 append() 会把新值添加到已有值集合的后面。
        // formData.append(name, value);
        // formData.append(name, value, filename);
        // name
        // value中包含的数据对应的表单名称。
        // value
        // 表单的值。可以是USVString 或 Blob (包括子类型，如 File)。
        // filename 可选
        // 传给服务器的文件名称 (一个 USVString), 当一个 Blob 或 File 被作为第二个参数的时候， Blob 对象的默认文件名是 “blob”。 File 对象的默认文件名是该文件的名称。
        // 注意： 如果你指定一个 Blob 作为数据添加到 FormData 对象中， 文件名会被放在 “Content-Disposition” 头部（常常会根据浏览器变化而变化）传给服务器。
        formData.append("photo", blob);
        // 发起请求
        const { data } = await updateUserPhoto(formData);
        // 更新视图
        // data.data.photo这个为后端返回的一个http开头的地址
        this.$emit("update-photo", data.data.photo);
        // 关闭弹出层
        this.$emit("close");

        // 提示成功
        this.$toast.success("更新成功");
      } catch (error) {
        console.log(error);
        this.$toast.fail("更新失败");
      }
    },
  },
};
</script>

<style scoped lang="less">
.update-photo {
  background-color: #000;
  height: 100%;
  .toolbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    justify-content: space-between;
    .cancel,
    .confirm {
      width: 90px;
      height: 90px;
      font-size: 30px;
      display: flex;
      justify-content: center;
      align-items: center;
      color: #fff;
    }
  }
}
.img {
  display: block;
  max-width: 100%;
}
</style>
